package com.vay.de.dang.online.view;

import android.content.Context;
import android.graphics.Canvas;
import android.graphics.Color;
import android.graphics.Paint;
import android.graphics.Rect;
import android.graphics.RectF;
import android.graphics.Typeface;
import android.graphics.drawable.Drawable;
import android.util.AttributeSet;
import android.view.MotionEvent;
import android.view.View;

import androidx.annotation.Nullable;

import com.vay.de.dang.online.VnApp;
import com.vay.de.dang.online.R;
import com.vay.de.dang.online.util.VnUtil;
import com.vay.de.dang.online.resp.RFinancialProductDto;

import java.util.ArrayList;
import java.util.Collections;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

public class LoanAmountSelector extends View {

    private Rect bgRect = new Rect();
    private RectF touchRect = new RectF();
    private Drawable bgDrawable;
    private Drawable proDrawable;
    private Drawable indicator;
    private int indicatorWidth;
    private int indicatorHeight;
    private int contentRectHeight;
    private int padding;
    private int touchPadding = 10;
    private Paint paint1;
    private Paint paint2;

    private int progress = 0;
    private int progressIndex = 0;
    private int progressMoney = 0;
    private int minAmount;
    private int maxAmount;
    private int offsetY;

    private List<Integer> moneys = new ArrayList<>();
    private Map<Integer, List<RFinancialProductDto>> moneyMap = new HashMap<>();
    private OnLoanProductCallback mCallback;

    public LoanAmountSelector(Context context, @Nullable AttributeSet attrs) {
        super(context, attrs);

        paint1 = new Paint();
        paint1.setAntiAlias(true);
        paint1.setColor(Color.parseColor("#43AE63"));
        paint1.setTextSize(VnApp.getDimension(R.dimen.f14));

        paint2 = new Paint();
        paint2.setAntiAlias(true);
        paint2.setColor(Color.parseColor("#43AE63"));
        paint2.setTextSize(VnApp.getDimension(R.dimen.f18));
        paint2.setTypeface(Typeface.DEFAULT_BOLD);

        padding = VnApp.getDimension(R.dimen.x16);
        contentRectHeight = VnApp.getDimension(R.dimen.x10);
        offsetY = VnApp.getDimension(R.dimen.x10);
        indicatorWidth = indicatorHeight = VnApp.getDimension(R.dimen.x20);
        bgDrawable = context.getDrawable(R.drawable.seekbar_bg);
        proDrawable = context.getDrawable(R.drawable.seekbar_pro);
        indicator = context.getDrawable(R.drawable.bg_seekbar_p);
    }

    @Override
    public boolean onTouchEvent(MotionEvent event) {

        final int action = event.getAction();
        final float px = event.getX();
        final float py = event.getY();
        if (action == MotionEvent.ACTION_DOWN
                || action == MotionEvent.ACTION_MOVE
                || action == MotionEvent.ACTION_CANCEL) {
            updateProgress(px, py);
        }

        return true;
    }

    private void updateProgress(float x, float y) {
        if (!touchRect.contains((int) x, (int) y)) return;
        float newProgress = (x - bgRect.left) / bgRect.width();
        if (newProgress >= 0.98) newProgress = 1.0f;

        // 是否可以用
        int newMoney = (int) (minAmount + (maxAmount - minAmount) * newProgress);
        int targetMoney = minAmount;

        if (newMoney <= minAmount) {
            targetMoney = minAmount;
        } else if (newMoney >= maxAmount) {
            targetMoney = maxAmount;
        } else {
            int minMoney = moneys.get(0);
            int maxMoney = moneys.get(0);
            for (int index = 0; index < moneys.size() - 1; index++) {
                int next = moneys.get(index + 1);
                int amount = moneys.get(index);
                if (newMoney >= amount && newMoney < next) {
                    minMoney = moneys.get(index);
                    maxMoney = moneys.get(index + 1);
                }
            }

            int half = (minMoney + maxMoney) / 2;
            if (newMoney < half) {
                targetMoney = minMoney;
            } else {
                targetMoney = maxMoney;
            }
        }


        int index = moneys.indexOf(targetMoney);
        int pp = (int) (((float) index / (moneys.size() - 1)) * 100);
        if (pp != progress) {
            progress = pp;
            progressIndex = index;
            progressMoney = targetMoney;
            List<RFinancialProductDto> temp = moneyMap.get(targetMoney);
            if (mCallback != null) mCallback.callback(temp);
            invalidate();
        }
    }

    @Override
    protected void onDraw(Canvas canvas) {
        int width = getWidth();
        int height = getHeight();
        if (width == 0 || height == 0) return;

        int left, top, right, bottom;
        int cw, ch;

        // 背景
        cw = width - padding * 2;
        left = padding;
        top = (height - contentRectHeight) / 2;
        right = left + cw;
        bottom = top + contentRectHeight;
        bgRect.set(left, top, right, bottom);
        touchRect.set(left, top - touchPadding, right, bottom + touchPadding);
        bgDrawable.setBounds(left, top, right, bottom);
        bgDrawable.draw(canvas);

        // 进度
        float p = (float) progress / 100;
        int proRight = left + (int) (bgRect.width() * p);
        proDrawable.setBounds(bgRect.left, bgRect.top, proRight, bgRect.bottom);
        proDrawable.draw(canvas);

        // 标注文本
        // 最小
        // int offsetY = 20;
        Paint.FontMetrics fm = paint1.getFontMetrics();
        float baseLine = fm.descent - ((fm.bottom - fm.top) - (fm.descent - fm.ascent)) / 2;
        float textHeight = fm.descent - fm.ascent;
        float textWith;
        float textDy = bgRect.bottom + textHeight - baseLine;
        float textDx;

        // 最小
        String str = VnUtil.toMoneyStr2(minAmount);
        textWith = paint1.measureText(str);
        textDx = bgRect.left/* - textWith / 2*/;
        canvas.drawText(str, textDx, textDy + offsetY, paint1);

        // 最大
        str = VnUtil.toMoneyStr2(maxAmount);
        textWith = paint1.measureText(str);
        textDx = bgRect.right - textWith;
        canvas.drawText(str, textDx, textDy + offsetY, paint1);

        // 当前
        //str = AllUtil.toMoney2String(minAmount + (int) ((maxAmount - minAmount) * p));
        str = VnUtil.toMoneyStr2(progressMoney);
        fm = paint2.getFontMetrics();
        baseLine = fm.descent - ((fm.bottom - fm.top) - (fm.descent - fm.ascent)) / 2;
        textHeight = fm.descent - fm.ascent;
        textWith = paint2.measureText(str);
        textDy = bgRect.top - (baseLine * 6.0f);
        textDx = bgRect.left + (bgRect.width() * p) - (textWith * p);
        canvas.drawText(str, textDx, textDy, paint2);

        // 图标
        int indicatorX = (int) (bgRect.left + (bgRect.width() * p) - indicatorWidth / 2);
        int indicatorY = (int) (bgRect.top - (indicatorWidth - bgRect.height()) / 2);
        indicator.setBounds(indicatorX, indicatorY,
                indicatorX + indicatorWidth, indicatorY + indicatorHeight);
        indicator.draw(canvas);
    }

    public void loadLoanAmount(List<RFinancialProductDto> list) {
        if (list == null || list.isEmpty()) return;

        Collections.sort(list, (o1, o2) -> {
            if (o1.getFinancialProductsAmount() > o2.getFinancialProductsAmount()) return 1;
            else if (o1.getFinancialProductsAmount() < o2.getFinancialProductsAmount()) return -1;
            else return 0;
        });

        minAmount = (int) list.get(0).getFinancialProductsAmount();
        maxAmount = (int) list.get(list.size() - 1).getFinancialProductsAmount();
        moneyMap.clear();
        moneys.clear();
        for (RFinancialProductDto item : list) {
            int key = (int) item.getFinancialProductsAmount();
            List<RFinancialProductDto> temp = moneyMap.get(key);
            if (temp == null) {
                moneyMap.put(key, temp = new ArrayList<>());
                moneys.add(key);
            }
            temp.add(item);
        }

        progress = 100;
        progressIndex = list.size() - 1;
        progressMoney = maxAmount;
        if (mCallback != null) {
            mCallback.callback(moneyMap.get(maxAmount));
        }

        invalidate();
    }

    public void setOnCallback(OnLoanProductCallback callback) {
        mCallback = callback;
    }

    public interface OnLoanProductCallback {

        void callback(List<RFinancialProductDto> list);
    }
}
